package com.ajk.server.service.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ajk.message.service.EasemobService;
import com.ajk.server.controller.events.CreditsEvent;
import com.ajk.server.dao.UsersHobbyRelMapper;
import com.ajk.server.dao.UsersMapper;
import com.ajk.server.exception.AjkException;
import com.ajk.server.exception.ErrorConstant;
import com.ajk.server.model.CreditsCategory;
import com.ajk.server.model.PatientEventDay;
import com.ajk.server.model.Users;
import com.ajk.server.model.UsersHobbyRel;
import com.ajk.server.model.query.UsersQuery;
import com.ajk.server.model.request.UserReq;
import com.ajk.server.model.response.TestAnswerRes;
import com.ajk.server.model.response.UserRes;
import com.ajk.server.service.CreditsHistoryService;
import com.ajk.server.service.EasemobMessageService;
import com.ajk.server.service.PatientEventService;
import com.ajk.server.service.TestAnswerService;
import com.ajk.server.service.UsersService;
import com.ajk.server.utils.FileStoreUtil;
import com.ajk.server.utils.MD5Tools;
import com.ajk.server.utils.QRCodeUtil;
import com.ajk.server.utils.SpringContextUtil;
import com.ajk.shop.model.response.SimpleUserProfileRes;

/**
 * 用户表  <br>
 * t_users <br>
 * v1.0 2016-05-01
 */
@Service
public class UsersServiceImpl implements UsersService {
	private static final Logger logger = LoggerFactory.getLogger(UserInfoServiceImpl.class);

	@Autowired
	private UsersMapper usersMapper;

	@Autowired
	private UsersHobbyRelMapper usersHobbyRelMapper;
	
	@Autowired
	EasemobMessageService easemobMessageService;
	
	@Autowired
	CreditsHistoryService creditsHistoryService;

	@Autowired
	EasemobService easemobService;
	
	@Autowired
	TestAnswerService testAnswerService;
	
	@Autowired
	PatientEventService patientEventService;
	
	
	/**
	 *根据ID删除 用户表
	 */
	@Override
	public Integer deleteUsersById(Integer id){
		return usersMapper.deleteById(id);
	}

	/**
	 *新增 用户表
	 */
	@Override
	@Transactional
	public Integer batchInsertUsers(List<? extends Users> userss){
		if (CollectionUtils.isNotEmpty(userss)) {
			for (Users users : userss) {
				users.dealWith();
			}
		}
		Integer count = usersMapper.batchInsert(userss);
		return count;
	}
	/**
	 *新增 用户表
	 */
	@Override
	@Transactional
	public Integer insertUsers(Users domain){
		domain.dealWith();
		usersMapper.insert(domain);
		Integer id = domain.getId();
		return id;
	}

	/**
	 *更新 用户表
	 */
	@Override
	@Transactional
	public Integer updateUsers(UserReq myProfile){
		Integer userId = myProfile.getId();
		
		UserRes userFromDb = usersMapper.findById(userId);
		if(userFromDb==null){
			AjkException ajkException =  new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "账号不存在");
			logger.info("修改个人信息失败",ajkException);
			throw ajkException;
		}
		if (myProfile.getHeight()==null) {
			myProfile.setHeight(userFromDb.getHeight());
		}
		if(myProfile.getWeight()==null){
			myProfile.setWeight(userFromDb.getWeight());
		}
		myProfile.dealWith();
		List<Integer> deleteHobbyIds = myProfile.getDeleteHobbyIds();
		List<String> hobbyNames = myProfile.getAddHobbys();
		if (CollectionUtils.isNotEmpty(hobbyNames)) {
			for (String string : hobbyNames) {
				if(StringUtils.length(string)>50){
					AjkException ajkException =  new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "爱好【"+string+"】不能超过50个字符");
					logger.info("修改个人信息失败",ajkException);
					throw ajkException;
				}
			}
		}

		//删除指定的爱好
		if (CollectionUtils.isNotEmpty(deleteHobbyIds)) {
			usersHobbyRelMapper.deleteByIds(deleteHobbyIds);
		}

		//根据名称查询是否存在
		if (CollectionUtils.isNotEmpty(hobbyNames)) {
			List<UsersHobbyRel> usersHobbyRels = usersHobbyRelMapper.findByUserIdNames(hobbyNames, userId);
			Map<String, UsersHobbyRel> map = new HashMap<String, UsersHobbyRel>();
			if (CollectionUtils.isNotEmpty(usersHobbyRels)) {
				for (UsersHobbyRel usersHobbyRel : usersHobbyRels) {
					map.put(usersHobbyRel.getHobbyName(),usersHobbyRel);
				}
			}
			List<UsersHobbyRel> needInsertList = new ArrayList<UsersHobbyRel>();
			for (String string : hobbyNames) {
				if(!map.containsKey(string)){
					UsersHobbyRel rel = new UsersHobbyRel();
					rel.setHobbyId(13); //其他
					rel.setHobbyName(string);
					rel.setInUsed(1);
					rel.setUserId(userId);
					needInsertList.add(rel);
				}
			}
			if (CollectionUtils.isNotEmpty(needInsertList)) {
				usersHobbyRelMapper.batchInsert(needInsertList);
			}
		}
		Integer count = usersMapper.update(myProfile);
		String nameDb = userFromDb.getName();
		String nameParam = myProfile.getName();
		if(StringUtils.isNotEmpty(nameParam) && !StringUtils.equals(nameDb,nameParam)){
			//修改环信昵称
			easemobService.resetNickname(userId.toString(), nameParam);
		}
		
		//添加积分
		CreditsEvent event = new CreditsEvent(userId, userId, CreditsCategory.PERFECT_INFO);
		SpringContextUtil.getApplicationContext().publishEvent(event);
		
		return count;
	}

	/**
	 *根据ID查询 用户表
	 *
	 *
	 */
	public UserRes findUsersById(Integer id){
		UserRes result = usersMapper.findById(id);
		if(result!=null){
			result.dealWith();
			FileStoreUtil.dealWithAvatar(result);
			Integer creditsAmount = creditsHistoryService.findMyCreditsAmount(id);
			result.setCreditsAmount(creditsAmount);
			TestAnswerRes test = testAnswerService.findMyLastTestAnswerRes(id);
			if(test!=null){
				result.setQuestionScore(test.getScore());
			}
			Map<String, PatientEventDay> map = patientEventService.findMyLastPatient(id);
			result.setLastPatientEvent(map);
		}
		return result;
	}
	
	

	/**
	 *通过query 查询 用户表
	 */
	public List<Users> findUsersByQuery(UsersQuery query){
		query.dealWith();
		List<Users> result = usersMapper.findByQuery(query);
		if(CollectionUtils.isNotEmpty(result)) {
			Collections.sort(result, new Comparator<Users>() {

				@Override
				public int compare(Users o1, Users o2) {
					if(o1!=null && o2!=null && o1.getId()!=null && o2.getId()!=null){
						return o2.getId().compareTo(o1.getId());
					}
					return 0;
				}
			});
			
			for (Users users : result) {
				users.dealWith();
				FileStoreUtil.dealWithAvatar(users);
			}
		}
		return result;
	}	

	/**
	 *通过query count总条数
	 */
	public Integer countUsersByQuery(UsersQuery query){
		query.dealWith();
		Integer result = usersMapper.countByQuery(query);
		return result;
	}

	@Override
	public List<SimpleUserProfileRes> findSimpleUsersByIds(List<Integer> ids) {
		List<SimpleUserProfileRes> res = null;
		if (CollectionUtils.isNotEmpty(ids)) {
			res = usersMapper.findSimpleByIds(ids);

			if (CollectionUtils.isNotEmpty(res)) {
				for (SimpleUserProfileRes simpleUserProfileRes : res) {
					FileStoreUtil.dealWithAvatar(simpleUserProfileRes);
				}
			}
		}
		return res;
	}
	
	
	@Override
	public SimpleUserProfileRes findSimpleUsersById(Integer id) {
		SimpleUserProfileRes res = usersMapper.findSimpleById(id);
		return res;
	}

	/**
	 * 通过ids查询
	 */
	public List<Users> findUsersByIds(List<Integer> ids){
		List<Users> result = usersMapper.findByIds(ids);
		if(CollectionUtils.isNotEmpty(result)) {
			for (Users users : result) {
				users.dealWith();
				FileStoreUtil.dealWithAvatar(users);
			}
		}
		return result;
	}
	
	@Override
	public Map<Integer, Users> findUsersMapByIds(List<Integer> ids) {
		List<Users> list = findUsersByIds(ids);
		Map<Integer, Users> map = new HashMap<Integer, Users>();
		if (CollectionUtils.isNotEmpty(list)) {
			for (Users users : list) {
				users.dealWith();
				map.put(users.getId(), users);
			}
		}
		return map;
	}

	@Override
	public Users sysUserLogin(Users user) {
		if(user.getMobile()==null || user.getMobile().trim().length()==0){
			throw new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "账号不能为空");
		}
		UsersQuery uq = new UsersQuery();
		Users users = usersMapper.findByMobile(user.getMobile());
		if(null == users){
			throw new AjkException(ErrorConstant.ACCOUNT_NOT_FOUND.getErrorCode(), ErrorConstant.ACCOUNT_NOT_FOUND.getMsg());
		}
		String password = user.getPassword();
		String pwd = MD5Tools.MD5(password);
		if(!users.getPassword().equals(pwd)){
			throw new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "密码错误");
		}
		if(users!=null){
			users.dealWith();
		}
		return users;
	}

	@Override
	public UserRes findUsersByMobile(String mobile){
		UserRes userRes = usersMapper.findByMobile(mobile);
		if(userRes!=null){
			userRes.dealWith();
		}
		return userRes;
	}

	@Override
	public String getQRcode(Integer userId) {
		UserRes user = usersMapper.findById(userId);
		if(user == null) {
			throw new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "用户不存在");
		}
		//如果用户没有二维码，则重新生成二维码
		if(user.getQrcode() == null) {
			Users userDomain = new Users();
			userDomain.setId(user.getId());
			String qrcode = generateUserQRcode(userId);
			userDomain.setQrcode("ext_res/".concat(qrcode));
			usersMapper.update(userDomain);
			return FileStoreUtil.getBaseUrl().concat(userDomain.getQrcode());
		}else {
			return FileStoreUtil.getBaseUrl().concat(user.getQrcode());
		}
	}

	@Override
	public String generateUserQRcode(Integer userId) {
		String qrcodeFolder = "user/qrcode/";
		String destPath = FileStoreUtil.getExtResRoot().concat(qrcodeFolder);
		String qrcode = null;
		try {
			qrcode = QRCodeUtil.encode(userId.toString(), null, destPath, true);
		} catch (Exception e) {
			throw new AjkException(ErrorConstant.PARAM_ERROR.getErrorCode(), "获取二维码出错了 ".concat(e.getMessage()));
		}
		return qrcodeFolder.concat(qrcode);
	}
	
	

}	
